package view;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import model.Cell;
import model.QueenPlacer;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.net.URL;
import java.util.List;

/**
 * @author tymoshya
 * @since 25.08.12
 */
public class Board {
    private static final int ROW_COUNT = QueenPlacer.N;
    private static final int COL_COUNT = QueenPlacer.N;

    private final JFrame frame = new JFrame("Eight Queens Task");
    private final ImageIcon icon = createImageIcon("images/wqw.gif", "An icon");
    private final ImageIcon queenIcon = createImageIcon("images/Queen.JPG", "A queen");
    private final JPanel[][] squares = new JPanel[ROW_COUNT][COL_COUNT];

    private JPanel mainPanel;
    private JPanel chessBoardPanel;
    private JButton solveButton;
    private JPanel bottomPanel;
    private JPanel horizontalLabelsPanel;
    private JPanel verticalLabelsPanel;

    public Board() {
        frame.setIconImage(icon.getImage());
        frame.setJMenuBar(createMenuBar());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        prepareChessBoard(chessBoardPanel);
        frame.setContentPane(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);      //centres the form on screen
        frame.setVisible(true);
        //TODO Extract ActionListeners to separate class in controller package?
        solveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                cleanBoard();
                List<Cell> queens = QueenPlacer.place2();
                for (Cell queen : queens) {
                    squares[queen.getI()][queen.getJ()].add(new JLabel(queenIcon));
                    squares[queen.getI()][queen.getJ()].validate();
                }
            }
        });
    }


    private void prepareChessBoard(JPanel board) {
        board.setLayout(new GridLayout(ROW_COUNT, COL_COUNT));
        for (int i = 0; i < ROW_COUNT; i++) {
            for (int j = 0; j < COL_COUNT; j++) {
                squares[i][j] = new JPanel();
                if ((i + j) % 2 == 0) {
                    squares[i][j].setBackground(Color.white);
                } else {
                    squares[i][j].setBackground(Color.blue);
                }
                CellConstraints cc = new CellConstraints();
                board.add(squares[i][j], cc.xy(i + 1, j + 1));
            }
        }
        markChessBoardWithLabels();
    }

    private void cleanBoard() {
        for (int i = 0; i < ROW_COUNT; i++) {
            for (int j = 0; j < COL_COUNT; j++) {
                /**
                 * Surprisingly,
                 *          squares[i][j].removeAll(); and squares[i][j].validate();
                 * does not hide the components, so I explicitly make all the containers' components invisible
                 */
                Component[] components = squares[i][j].getComponents();
                for (Component component : components) {
                    component.setVisible(false);
                }
                squares[i][j].removeAll();
                squares[i][j].validate();
            }
        }
    }

    private void markChessBoardWithLabels() {
        JLabel label;
        CellConstraints cc = new CellConstraints();

        // Horizontals 1..8
        horizontalLabelsPanel.setLayout(new GridLayout(ROW_COUNT, 0));
        for (int i = 0; i < ROW_COUNT; i++) {
            label = new JLabel(String.valueOf(ROW_COUNT - i));
            label.setFont(new Font("Arial", Font.BOLD, 28));
            label.setForeground(Color.ORANGE);
            horizontalLabelsPanel.add(label, cc.xy(i + 1, 0));
        }
        horizontalLabelsPanel.validate();

        // Verticals A..H
        verticalLabelsPanel.setLayout(new GridLayout(0, COL_COUNT));
        String[] verticalLabels = {"A", "B", "C", "D", "E", "F", "G", "H"};
        for (int i = 0; i < COL_COUNT; i++) {
            label = new JLabel(" " + verticalLabels[i]);
            label.setFont(new Font("Arial", Font.BOLD, 28));
            label.setForeground(Color.ORANGE);
            verticalLabelsPanel.add(label, cc.xy(0, i + 1));
        }
        verticalLabelsPanel.validate();
    }

    private JMenuBar createMenuBar() {
        JMenuBar result;
        JMenu menu;
        JMenuItem menuItem;

        result = new JMenuBar();

        // 1st Menu
        menu = new JMenu("File");
        menu.setMnemonic(KeyEvent.VK_F);
        menu.getAccessibleContext().setAccessibleDescription("File menu");
        result.add(menu);

        menu.addSeparator();
        menuItem = new JMenuItem("Exit", KeyEvent.VK_E);
        menuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        menu.add(menuItem);

        // 2nd Menu
        menu = new JMenu("Help");
        menu.setMnemonic(KeyEvent.VK_H);
        result.add(menu);

        menu.addSeparator();
        menuItem = new JMenuItem("About", KeyEvent.VK_A);
        menuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                final String copyright = "\u00a9";
                JOptionPane.showMessageDialog(frame, copyright + " 2012 YAKIV TYMOSHENKO, MGR. ALL RIGHTS RESERVED",
                        "Eight Queens Task - version 1.0", JOptionPane.INFORMATION_MESSAGE, icon);
            }
        });
        menu.add(menuItem);

        return result;
    }

    private ImageIcon createImageIcon(String path, String description) {
        URL imgURL = getClass().getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL, description);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        mainPanel = new JPanel();
        mainPanel.setLayout(new FormLayout("fill:max(d;4px):noGrow,left:28px:noGrow,center:520px:noGrow,left:24px:noGrow,fill:max(d;4px):noGrow", "center:max(d;4px):noGrow,top:24px:noGrow,center:500px:noGrow,center:max(d;4px):noGrow,top:28px:noGrow,bottom:40px:noGrow,top:4dlu:noGrow"));
        chessBoardPanel = new JPanel();
        chessBoardPanel.setLayout(new BorderLayout(0, 0));
        chessBoardPanel.setPreferredSize(new Dimension(500, 500));
        CellConstraints cc = new CellConstraints();
        mainPanel.add(chessBoardPanel, cc.xy(3, 3, CellConstraints.FILL, CellConstraints.FILL));
        chessBoardPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), null));
        bottomPanel = new JPanel();
        bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        mainPanel.add(bottomPanel, cc.xy(3, 6, CellConstraints.FILL, CellConstraints.FILL));
        solveButton = new JButton();
        solveButton.setFont(UIManager.getFont("Button.font"));
        solveButton.setHorizontalTextPosition(11);
        solveButton.setText("Solve");
        solveButton.setVerticalAlignment(0);
        bottomPanel.add(solveButton);
        horizontalLabelsPanel = new JPanel();
        horizontalLabelsPanel.setLayout(new BorderLayout(0, 0));
        mainPanel.add(horizontalLabelsPanel, cc.xy(2, 3, CellConstraints.RIGHT, CellConstraints.FILL));
        horizontalLabelsPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), null));
        verticalLabelsPanel = new JPanel();
        verticalLabelsPanel.setLayout(new BorderLayout(0, 0));
        mainPanel.add(verticalLabelsPanel, new CellConstraints(3, 5, 1, 1, CellConstraints.FILL, CellConstraints.DEFAULT, new Insets(0, 16, 0, 0)));
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return mainPanel;
    }
}
